package com.ququ.syb.business.payment.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ququ.syb.business.payment.fegin.BalanceFegin;
import com.ququ.syb.business.payment.redis.RedisDao;
import com.ququ.syb.common.constant.FlowTypeConstant;
import com.ququ.syb.common.constant.RedisKeyConstant;
import com.ququ.syb.common.pojo.AccountChannelBalance;
import com.ququ.syb.common.pojo.PayOrder;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Service
public class BalanceBusinessService {

    private Logger logger = LoggerFactory.getLogger(BalanceBusinessService.class);

    @Autowired
    private BalanceFegin balanceFegin;
    @Autowired
    private RedisDao redisDao;

    /**
     * 付款方充值
     * @param payOrder
     * @return
     */
    public AccountChannelBalance payerRecharge(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getCreateaccount(),
                payOrder.getPaychannelid(),
                payOrder.getAmount()+payOrder.getPaycommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.RECHARGE,
                payOrder.getAppcode(),
                "付款方账户充值").getData();
        logger.debug("付款方账户充值后余额:{}",accountChannelBalance);
        if (payOrder.getPaycommission() > 0){
            accountChannelBalance = balanceFegin.addBalance(payOrder.getCreateaccount(),
                    payOrder.getPaychannelid(),
                    0-payOrder.getPaycommission(),
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.PAY_COMMISSION,
                    payOrder.getAppcode(),
                    "付款方手续费支出").getData();
            logger.debug("付款方账户扣除付款方手续费后余额:{}",accountChannelBalance);
        }
        return accountChannelBalance;
    }

    /**
     * 付款方扣款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance payerDeduct(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getCreateaccount(),
                payOrder.getPaychannelid(),
                0-payOrder.getAmount(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_BALANCE,
                payOrder.getAppcode(),
                "付款方账户付款支出").getData();
        logger.debug("付款方账户付款支出后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }

    /**
     * 收款方收款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance payeeReceipt(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getPayeeaccount(),
                payOrder.getPaychannelid(),
                payOrder.getAmount(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_RECEIPT,
                payOrder.getAppcode(),
                "收款方账户订单收款").getData();
        logger.debug("付款方账户订单收款后余额:{}",accountChannelBalance);
        if (payOrder.getPayeecommission() > 0){
            accountChannelBalance = balanceFegin.addBalance(payOrder.getPayeeaccount(),
                    payOrder.getPaychannelid(),
                    0-payOrder.getPayeecommission(),
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.PAY_COMMISSION,
                    payOrder.getAppcode(),
                    "收款方手续费支出").getData();
            logger.debug("收款方账户扣除收款方手续费后余额:{}",accountChannelBalance);
        }
        return accountChannelBalance;
    }


    /**
     * 订单分账转账
     */
    public void payeeDivide(PayOrder payOrder){
        if(StringUtils.isBlank(payOrder.getDivideinfo())){
            logger.debug("无分账信息。不进行分账余额处理");
            return;
        }
        long totalAmount = payOrder.getAmount()-payOrder.getPayeecommission();
        List<Map> divideList = JSON.parseArray(payOrder.getDivideinfo(),Map.class);
        for (Map<String,String> divide : divideList){
            String accountid = divide.get("accountid");
            Double percent = Double.valueOf(divide.get("percent"));
            if (accountid.equals(payOrder.getPayeeaccount()))
                continue;
            Long amount = new BigDecimal(totalAmount).multiply(new BigDecimal(percent)).setScale(0,BigDecimal.ROUND_HALF_UP).longValue();
            //从收款方账户转出
            AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getPayeeaccount(),
                    payOrder.getPaychannelid(),
                    0-amount,
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.PAY_DIVIDE,
                    payOrder.getAppcode(),
                    "收款方账户订单分账给"+accountid+"转出").getData();
            logger.debug("付款方账户订单分账给"+accountid+"转账后余额:{}",accountChannelBalance);
            //分账方账户转入
            accountChannelBalance = balanceFegin.addBalance(accountid,
                    payOrder.getPaychannelid(),
                    amount,
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.PAY_DIVIDE_RECEIPT,
                    payOrder.getAppcode(),
                    "分账方账户订单分账收入").getData();
            logger.debug("分账方账户"+accountid+"订单分账后余额:{}",accountChannelBalance);
        }
    }


    /**
     * 担保户收款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance assureReceipt(PayOrder payOrder){
        Jedis jedis = redisDao.getJedis();
        String assureAccountId = jedis.get(RedisKeyConstant.ASSURE_ACCOUNT);
        redisDao.close(jedis);
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(assureAccountId,
                payOrder.getPaychannelid(),
                payOrder.getAmount(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_ASSURE_RECEIPT,
                payOrder.getAppcode(),
                "担保账户订单收款").getData();
        logger.debug("担保账户订单收款后余额:{}",accountChannelBalance);
        if (payOrder.getPayeecommission() > 0){
            accountChannelBalance = balanceFegin.addBalance(assureAccountId,
                    payOrder.getPaychannelid(),
                    0-payOrder.getPayeecommission(),
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.PAY_COMMISSION,
                    payOrder.getAppcode(),
                    "担保账户收款方手续费支出").getData();
            logger.debug("担保账户扣除收款方手续费后余额:{}",accountChannelBalance);
        }
        return accountChannelBalance;
    }


    /**
     * 担保户扣款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance assureDeduct(PayOrder payOrder){
        Jedis jedis = redisDao.getJedis();
        String assureAccountId = jedis.get(RedisKeyConstant.ASSURE_ACCOUNT);
        redisDao.close(jedis);
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(assureAccountId,
                payOrder.getPaychannelid(),
                0-payOrder.getAmount()+payOrder.getPayeecommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_ASSURE_TRANSFER,
                payOrder.getAppcode(),
                "担保账户订单确认付款").getData();
        logger.debug("担保账户订单确认付款后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }

    /**
     * 担保退款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance assureRefund(PayOrder payOrder){
        Jedis jedis = redisDao.getJedis();
        String assureAccountId = jedis.get(RedisKeyConstant.ASSURE_ACCOUNT);
        redisDao.close(jedis);
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(assureAccountId,
                payOrder.getPaychannelid(),
                0-payOrder.getAmount()+payOrder.getPayeecommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_ASSURE_REFUND,
                payOrder.getAppcode(),
                "担保账户订单退款").getData();
        logger.debug("担保账户订单退款后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }

    /**
     * 收款方退款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance payeeRefund(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getPayeeaccount(),
                payOrder.getPaychannelid(),
                0-payOrder.getAmount()+payOrder.getPayeecommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.PAY_REFUND,
                payOrder.getAppcode(),
                "收款方账户订单退款").getData();
        logger.debug("收款方账户订单退款后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }


    /**
     * 通道账户收款
     * @param payOrder
     * @param channelAccountId
     * @return
     */
    public AccountChannelBalance channelAccountReceipt(PayOrder payOrder,String channelAccountId){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(channelAccountId,
                payOrder.getPaychannelid(),
                payOrder.getAmount()+payOrder.getPaycommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.CHANNEL_RECEIPT,
                payOrder.getAppcode(),
                "通道账户订单收款").getData();
        logger.debug("通道账户订单收款后余额:{}",accountChannelBalance);
        if (payOrder.getCostcommission() > 0) {
            accountChannelBalance = balanceFegin.addBalance(channelAccountId,
                    payOrder.getPaychannelid(),
                    0 - payOrder.getCostcommission(),
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.CHANNEL_PAY_COMMISSION,
                    payOrder.getAppcode(),
                    "通道账户手续费成本支出").getData();
            logger.debug("通道账户扣除手续费成本后余额:{}", accountChannelBalance);
        }
        return accountChannelBalance;
    }


    /**
     * 通道退款
     * @param payOrder
     * @param channelAccountId
     * @return
     */
    public AccountChannelBalance channelAccountRefund(PayOrder payOrder,String channelAccountId){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(channelAccountId,
                payOrder.getPaychannelid(),
                0-(payOrder.getAmount()+payOrder.getPaycommission())+payOrder.getCostcommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.CHANNEL_REFUND,
                payOrder.getAppcode(),
                "通道账户订单退款").getData();
        logger.debug("通道账户订单退款后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }

    /**
     * 应用收款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance applicationAccountReceipt(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getAppcode(),
                payOrder.getPaychannelid(),
                payOrder.getAmount()+payOrder.getPaycommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.APPLICATION_RECEIPT,
                payOrder.getAppcode(),
                "应用账户订单收款").getData();
        logger.debug("应用账户订单收款后余额:{}",accountChannelBalance);
        if (payOrder.getCostcommission() > 0) {
            accountChannelBalance = balanceFegin.addBalance(payOrder.getAppcode(),
                    payOrder.getPaychannelid(),
                    0 - payOrder.getCostcommission(),
                    1,
                    payOrder.getTradenum(),
                    FlowTypeConstant.APPLICATION_PAY_COMMISSION,
                    payOrder.getAppcode(),
                    "应用通道账户通道手续费成本支出").getData();
            logger.debug("应用账户扣除通道手续费成本后余额:{}", accountChannelBalance);
        }
        return accountChannelBalance;
    }


    /**
     * 订单应用退款
     * @param payOrder
     * @return
     */
    public AccountChannelBalance applicationAccountRefund(PayOrder payOrder){
        AccountChannelBalance accountChannelBalance = balanceFegin.addBalance(payOrder.getAppcode(),
                payOrder.getPaychannelid(),
                0-(payOrder.getAmount()+payOrder.getPaycommission())+payOrder.getCostcommission(),
                1,
                payOrder.getTradenum(),
                FlowTypeConstant.APPLICATION_REFUND,
                payOrder.getAppcode(),
                "应用账户订单退款").getData();
        logger.debug("应用账户订单退款后余额:{}",accountChannelBalance);
        return accountChannelBalance;
    }

}
